package de.ret_world.openrpgstudio.editor.gui;

import buoy.event.CommandEvent;
import buoy.event.WindowClosingEvent;
import buoy.widget.*;
import de.ret_world.openrpgstudio.editor.Configuration;
import de.ret_world.openrpgstudio.editor.Main;
import de.ret_world.openrpgstudio.editor.helpers.Internationalization;
import de.ret_world.openrpgstudio.editor.helpers.ScriptTools;
import de.ret_world.openrpgstudio.editor.plugininterfaces.DatabasePlugin;
import java.awt.Insets;
import java.awt.Rectangle;
import java.util.ArrayList;
import org.apache.log4j.Logger;
import org.java.plugin.PluginClassLoader;
import org.java.plugin.PluginLifecycleException;
import org.java.plugin.PluginManager;
import org.java.plugin.registry.Extension;
import org.java.plugin.registry.ExtensionPoint;

/**
 * Dialog for main database settings and creation. You can use the Plugin Extension "Database" to create a tab to show the database panel of your
 * library.
 *
 * @author emu
 */
public class DatabaseDialog {
    
    private BDialog dialog;
    private BFrame parent;
    private PluginManager manager;
    private Main main;
    private ArrayList<DatabasePlugin> databasePlugins;
    
    public DatabaseDialog(BFrame parent, Main main) {
        this.parent = parent;
        this.main = main;
        this.manager = main.getManager();
        databasePlugins = new ArrayList<>();
    }

    /**
     * Shows the DatabaseDialog.
     */
    public void showDialog(PluginClassLoader cl) {
        Internationalization intn = Internationalization.getInstance();
        
        ScriptTools.getInstance().executeStartScript();
        
        dialog = new BDialog(parent, intn.getString("MENU.DATABASE"), true);
        
        BorderContainer bc = new BorderContainer();
        BTabbedPane tabs = new BTabbedPane();

        //Plugin Extension Point "Database"
        DatabasePlugin plugin;
        BSplitPane pluginContainer = null;
        ExtensionPoint toolExtPoint = manager.getRegistry().getExtensionPoint(Main.PLUGIN_ID, "Database");
        for (Extension ext : toolExtPoint.getConnectedExtensions()) {
            //initialize the plugin
            if (manager.isPluginEnabled(ext.getDeclaringPluginDescriptor())) {
                try {
                    // Activate plug-in that declares extension.
                    manager.activatePlugin(ext.getDeclaringPluginDescriptor().getId());
                    main.reloadInternationalization();
                    // Get plug-in class loader.
                    ClassLoader classLoader = manager.getPluginClassLoader(ext.getDeclaringPluginDescriptor());
                    // Load Tool class.
                    Class<?> clazz = classLoader.loadClass(ext.getParameter("class").valueAsString());
                    // Create Tool instance.
                    plugin = (DatabasePlugin) clazz.newInstance();
                    databasePlugins.add(plugin);
                    pluginContainer = new BSplitPane(BSplitPane.HORIZONTAL);
                    // Initialize class instance according to interface contract.
                    plugin.setParent(dialog);
                    plugin.init(pluginContainer);
                    
                    tabs.add(pluginContainer, ext.getParameter("name").valueAsString());
                } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | PluginLifecycleException ex) {
                    Logger.getLogger(DatabaseDialog.class).error(ex);
                }
            }
        }
        
        bc.add(BOutline.createEtchedBorder(tabs, false), BorderContainer.CENTER, new LayoutInfo(LayoutInfo.CENTER, LayoutInfo.BOTH));
        
        LayoutInfo li = new LayoutInfo(LayoutInfo.WEST, LayoutInfo.HORIZONTAL, new Insets(5, 5, 5, 5), null);
        
        BorderContainer bc2 = new BorderContainer();
        BButton btn = new BButton(intn.getString("OK"));
        btn.addEventLink(CommandEvent.class, this, "ok");
        bc2.add(btn, BorderContainer.EAST, li);
        btn = new BButton(intn.getString("CANCEL"));
        btn.addEventLink(CommandEvent.class, this, "cancel");
        bc2.add(btn, BorderContainer.CENTER, li);
        bc.add(bc2, BorderContainer.SOUTH, new LayoutInfo(LayoutInfo.EAST, LayoutInfo.NONE, new Insets(5, 5, 5, 5), null));
        
        dialog.setContent(bc);
        dialog.addEventLink(WindowClosingEvent.class, this, "cancel");
        
        Configuration config = Configuration.getInstance(Main.PLUGIN_ID);
        int x = Integer.parseInt(config.getProperty("db.dialog.loc.x", "150"));
        int y = Integer.parseInt(config.getProperty("db.dialog.loc.y", "150"));
        int w = Integer.parseInt(config.getProperty("db.dialog.size.w", "900"));
        int h = Integer.parseInt(config.getProperty("db.dialog.size.h", "700"));
        
        dialog.setBounds(new Rectangle(x, y, w, h));
        dialog.setResizable(true);
        dialog.setVisible(true);
    }
    
    private void cancel() {
        saveConfig();
        dialog.dispose();
    }
    
    private void saveConfig() {
        Configuration config = Configuration.getInstance(Main.PLUGIN_ID);
        if (dialog != null) {
            Logger.getLogger(DatabaseDialog.class).info("Saving configuration files");
            
            config.setProperty("db.dialog.loc.x", "" + dialog.getBounds().x);
            config.setProperty("db.dialog.loc.y", "" + dialog.getBounds().y);
            config.setProperty("db.dialog.size.w", "" + dialog.getBounds().width);
            config.setProperty("db.dialog.size.h", "" + dialog.getBounds().height);
            
            dialog.dispose();
        }
        if (config != null) {
            config.storeConfig();
        }
    }
    
    private void ok() {
        if (databasePlugins != null) {
            for (DatabasePlugin o : databasePlugins) {
                o.save();
            }
        }
        saveConfig();
        dialog.dispose();
    }
}
